package qiniufile

import (
	"context"
	"strconv"
	"strings"

	"mall/common/utils/pointy"
	"mall/service/attachment/rpc/attachmentclient"
	"mall/service/backend/api/internal/svc"
	"mall/service/backend/api/internal/types"
	"mall/service/blog/rpc/blogclient"
	"mall/service/forum/rpc/forumclient"
	"mall/service/product/rpc/productclient"
	"mall/service/promotion/rpc/promotionclient"
	"mall/service/user/rpc/userclient"

	"github.com/zeromicro/go-zero/core/logx"
)

// todo:未实现完整
type DeleteFileLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewDeleteFileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteFileLogic {
	return &DeleteFileLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *DeleteFileLogic) DeleteFile(req *types.DeleteQiniuFileReq) (resp *types.BaseMsgResp, err error) {
	if len(req.Ids) == 0 {
		return nil, nil
	}

	var ids []string
	var idMap = make(map[uint64]struct{})
	for _, v := range req.Ids {
		id, err := strconv.ParseUint(v, 10, 64)
		if err != nil {
			return nil, err
		}
		if id > 0 {
			if _, ok := idMap[id]; !ok {
				idMap[id] = struct{}{}
			}
		}
	}

	// 要同时删除七牛云图片，先查询别的模块有没有使用到该图片
	if req.WithQiniu != nil && *req.WithQiniu > 0 && req.RetentionTime != nil && *req.RetentionTime > 0 {
		userIds, err := l.getUserAttachmentLogList(req.Ids)
		if err != nil {
			return nil, err
		}
		for _, id := range userIds {
			if _, ok := idMap[id]; ok {
				delete(idMap, id)
			}
		}

		blogIds, err := l.getBlogAttachmentLogList(req.Ids)
		if err != nil {
			return nil, err
		}
		for _, id := range blogIds {
			if _, ok := idMap[id]; ok {
				delete(idMap, id)
			}
		}

		forumIds, err := l.getForumAttachmentLogList(req.Ids)
		if err != nil {
			return nil, err
		}
		for _, id := range forumIds {
			if _, ok := idMap[id]; ok {
				delete(idMap, id)
			}
		}

		productIds, err := l.getPromotionAttachmentLogList(req.Ids)
		if err != nil {
			return nil, err
		}
		for _, id := range productIds {
			if _, ok := idMap[id]; ok {
				delete(idMap, id)
			}
		}

		promotionIds, err := l.getPromotionAttachmentLogList(req.Ids)
		if err != nil {
			return nil, err
		}
		for _, id := range promotionIds {
			if _, ok := idMap[id]; ok {
				idMap[id] = struct{}{}
			}
		}
	}

	if len(idMap) > 0 {
		for i, _ := range idMap {
			ids = append(ids, strconv.FormatUint(i, 10))
		}
	}

	if len(ids) == 0 {
		return nil, nil
	}

	res, err := l.svcCtx.AttachmentRpc.BackendDeleteFile(l.ctx, &attachmentclient.DeleteFileReq{
		Ids: req.Ids,
	})
	if err != nil {
		return
	}

	return &types.BaseMsgResp{
		Success: true,
		Msg:     l.svcCtx.Trans.Trans(l.ctx, res.Msg),
	}, nil
}

func (l *DeleteFileLogic) getUserAttachmentLogList(ids []string) ([]uint64, error) {
	//orderStr := pointy.GetPointer("id:1")
	//orderBys := util.ParseSorter(orderStr)
	res, err := l.svcCtx.UserRpc.BackendGetAttachmentLogList(l.ctx, &userclient.BackendAttachmentLogListReq{
		Ids: pointy.GetPointer(strings.Join(ids, ",")),
		//OrderBy  :orderBys,
	})
	if err != nil {
		return nil, err
	}
	var rids []uint64
	if len(res.List) > 0 {
		for _, v := range res.List {
			if v.Id != nil && *v.Id > 0 {
				rids = append(rids, *v.Id)
			}
		}
	}
	return rids, nil
}

func (l *DeleteFileLogic) getBlogAttachmentLogList(ids []string) ([]uint64, error) {
	//orderStr := pointy.GetPointer("id:1")
	//orderBys := util.ParseSorter(orderStr)
	res, err := l.svcCtx.BlogRpc.BackendGetAttachmentLogList(l.ctx, &blogclient.BackendAttachmentLogListReq{
		Ids: pointy.GetPointer(strings.Join(ids, ",")),
		//OrderBy  :orderBys,
	})
	if err != nil {
		return nil, err
	}
	var rids []uint64
	if len(res.List) > 0 {
		for _, v := range res.List {
			if v.Id != nil && *v.Id > 0 {
				rids = append(rids, *v.Id)
			}
		}
	}
	return rids, nil
}

func (l *DeleteFileLogic) getForumAttachmentLogList(ids []string) ([]uint64, error) {
	//orderStr := pointy.GetPointer("id:1")
	//orderBys := util.ParseSorter(orderStr)
	res, err := l.svcCtx.ForumRpc.BackendGetAttachmentLogList(l.ctx, &forumclient.BackendAttachmentLogListReq{
		Ids: pointy.GetPointer(strings.Join(ids, ",")),
		//OrderBy  :orderBys,
	})
	if err != nil {
		return nil, err
	}
	var rids []uint64
	if len(res.List) > 0 {
		for _, v := range res.List {
			if v.Id != nil && *v.Id > 0 {
				rids = append(rids, *v.Id)
			}
		}
	}
	return rids, nil
}

func (l *DeleteFileLogic) getProductAttachmentLogList(ids []string) ([]uint64, error) {
	//orderStr := pointy.GetPointer("id:1")
	//orderBys := util.ParseSorter(orderStr)
	res, err := l.svcCtx.ProductRpc.BackendGetAttachmentLogList(l.ctx, &productclient.BackendAttachmentLogListReq{
		Ids: pointy.GetPointer(strings.Join(ids, ",")),
		//OrderBy  :orderBys,
	})
	if err != nil {
		return nil, err
	}
	var rids []uint64
	if len(res.List) > 0 {
		for _, v := range res.List {
			if v.Id != nil && *v.Id > 0 {
				rids = append(rids, *v.Id)
			}
		}
	}
	return rids, nil
}

func (l *DeleteFileLogic) getPromotionAttachmentLogList(ids []string) ([]uint64, error) {
	//orderStr := pointy.GetPointer("id:1")
	//orderBys := util.ParseSorter(orderStr)
	res, err := l.svcCtx.PromotionRpc.BackendGetAttachmentLogList(l.ctx, &promotionclient.BackendAttachmentLogListReq{
		Ids: pointy.GetPointer(strings.Join(ids, ",")),
		//OrderBy  :orderBys,
	})
	if err != nil {
		return nil, err
	}
	var rids []uint64
	if len(res.List) > 0 {
		for _, v := range res.List {
			if v.Id != nil && *v.Id > 0 {
				rids = append(rids, *v.Id)
			}
		}
	}
	return rids, nil
}
